﻿
namespace System.Linq.Functional
{
    public sealed class ContinuationException
    {
        public static void GenerateTest<T>(
            Func<T> generate,
            Func<T, bool> test,
            Action<T> ifTrue,
            Action<T> ifFalse)
        {
            T value = generate();
            (test(value) ? ifTrue : ifFalse)(value);
        }

        public static bool TryBool(Action actionProcedure)
        {
            try
            {
                actionProcedure();
                return true;
            }

            catch (Exception)
            {
                return false;
            }
        }

        public static Exception TryException(Action actionProcedure)
        {
            try
            {
                actionProcedure();
                return null;
            }

            catch (Exception ex)
            {
                return ex;
            }
        }

        public static void TryIgnore(Action actionProcedure)
        {
            try
            {
                actionProcedure();
            }

            catch (Exception)
            {
                // Ignore 
            }
        }
      
        public static void TryCatch(
            Action actionProcedure,
            Action<Exception> catchClause)
        {
            try
            {
                actionProcedure();
            }

            catch (Exception ex)
            {
                catchClause(ex);
            }
        }

        public static T TryCatch<T>(
            Func<T> actionFunction,
            Func<Exception, T> catchClause)
        {
            T returnVal;

            try
            {
                returnVal = actionFunction();
            }

            catch (Exception ex)
            {
                returnVal = catchClause(ex);
            }

            return returnVal;
        }

        public static void TryCatchFinally(
            Action actionProcedure,
            Action<Exception> catchClause,
            Action finallyClause)
        {
            try
            {
                actionProcedure();
            }

            catch (Exception ex)
            {
                catchClause(ex);
            }

            finally
            {
                finallyClause();
            }
        }

        public static T TryCatchFinally<T>(
            Func<T> actionFunction,
            Func<Exception, T> catchClause,
            Action finallyClause)
        {
            T returnVal;

            try
            {
                returnVal = actionFunction();
            }

            catch (Exception ex)
            {
                returnVal = catchClause(ex);
            }

            finally
            {
                finallyClause();
            }

            return returnVal;
        }

        public static void TryFinally(
            Action actionProcedure,
            Action finallyClause)
        {
            try
            {
                actionProcedure();
            }

            finally
            {
                finallyClause();
            }
        }
    }
}
